package model

import (
	"dta-apk/utils"
	"fmt"

	"github.com/glebarez/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

// 公共字段模型
type Model struct {
	gorm.Model
	ID uint `gorm:"column:id;primarykey" json:"id"`
}

// 分页请求参数结构体
type Pagination struct {
	PageNum  int
	PageSize int
	Where    interface{}
}

// 分页结果模型
type PageResult struct {
	TotalCount  int         `json:"totalCount"`  // 数据总条数
	TotalPages  int         `json:"totalPages"`  // 分页总数
	CurrentPage int         `json:"currentPage"` // 当前页
	PageSize    int         `json:"pageSize"`    // 每页数据大小
	Data        interface{} `json:"data"`        // 数据
}

var DbConn *gorm.DB

// 数据库连接初始化
func init() {
	db, err := gorm.Open(sqlite.Open("apk.db"), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info), //配置日志级别，打印出所有的sql
	})

	if err != nil {
		panic(err)
	}
	// 自动迁移
	err = db.AutoMigrate(
		&AppModel{},
		&AppInfoModel{},
		&AppPlatModel{},
		&VersionModel{},
		&FileModel{},
		&AppPublishModel{},
	)
	if err != nil {
		panic(err)
	}

	DbConn = db
}

// 分页查询数据
func Page(pagination Pagination, model interface{}) (PageResult, error) {
	var pageResult PageResult
	var totalCount int64
	// 获取总记录数
	if err := DbConn.Model(model).Count(&totalCount).Error; err != nil {
		return pageResult, err
	}

	// 计算总页数
	totalPages := (int(totalCount) + pagination.PageSize - 1) / pagination.PageSize
	// 计算偏移量
	offset := (pagination.PageNum - 1) * pagination.PageSize
	// 执行分页查询
	result := DbConn.Model(model).Where(pagination.Where).Limit(pagination.PageSize).Offset(offset).Find(model)
	if result.Error != nil {
		fmt.Println(result.Error)
		return pageResult, result.Error
	}
	pageResult.TotalCount = int(totalCount)
	pageResult.TotalPages = totalPages
	pageResult.CurrentPage = pagination.PageNum
	pageResult.PageSize = pagination.PageSize
	pageResult.Data = model

	return pageResult, nil
}

// 条件查询
func FindOne(model interface{}, where interface{}) bool {
	result := DbConn.Model(model).Where(where).First(model)
	if result.Error != nil || result.RowsAffected == 0 {
		utils.LogError(utils.ErrorLog{Message: result.Error.Error()})
		return false
	}
	return true
}

// 条件查询
func FindAll(model interface{}, where interface{}) bool {
	result := DbConn.Model(model).Where(where).Find(model)
	if result.Error != nil || result.RowsAffected == 0 {
		fmt.Println(result.Error)
		return false
	}
	return true
}

// 主键查询
func FindById(model interface{}, id any) bool {
	result := DbConn.Model(model).First(model, id)
	if result.Error != nil || result.RowsAffected == 0 {
		fmt.Println(result.Error)
		return false
	}
	return true
}

// 保存数据
func Save(model interface{}) error {
	result := DbConn.Create(model)
	return result.Error
}

// 修改数据
func Update(model interface{}) error {
	result := DbConn.Save(model)
	return result.Error
}

// 根据条件查询，存在更新数据，如果不存在就创建
func UpdateOrCreate(model interface{}, where interface{}) error {
	updateModel := model
	result := DbConn.Model(model).Where(where).Find(model)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		result = DbConn.Create(updateModel)
		if result.Error != nil {
			return result.Error
		}
		if result.RowsAffected == 0 {
			return &DbError{message: "更新或新建失败"}
		}
	} else {
		result = DbConn.Model(model).Where(where).Updates(updateModel)
		if result.Error != nil || result.RowsAffected == 0 {
			return result.Error
		}
	}

	return nil
}

// 自定义错误
type DbError struct {
	message string
}

func (e *DbError) Error() string {
	return e.message
}
